Site to Site VPN via OpenVPN
 

Una de las enormes ventajas que tiene trabajar con LINUX es la manoiobrabilidad que permiten las diferentes distribuciones, incluse aquellas que no fueron diseñadas para el propósito que nosotros querramos darle.

Hace un tiempo me encontre con la necesidad de implementar una VPN Site-to-Site, entre 2 sites que no tenían IP Fija, ni posibilidad de tenerla por los ISPs disponibles en la zona

En uno de esos sites, corríamos un LINUX como firewall y en el otro un router.., mismo que carecía de capacidades de VPN, ni como server ni como cliente...

A priori, la primer solución sería que los clientes en el site 2 establecieran una VPN al site 1 en forma individual, pero no solo era engorroso sino altamente problemático.. asi que fue descartada..

OpenVPN al rescate...

Entre muchas opciones disponibles, optamos por implementar OpenVPN.
Para ello, eliminamos el router del site 2 y pusimos en su lugar un Linux CentOS

OpenVPN... tiene una versión community que es libre y puede descargarse y utlizarse

Esquema

Salteando la instalación de OpenVPN es es bastante simple, vamos a pasar al esquema de configuración, para lo cual plantearemos el esquema de conexión a realizar y los nombres que utilizaremos en cada extremo (recordando que en ambos utilizamos ip dinámicas, por lo que no podemos utilizar una ip para conexión)

De acuerdo la imagen arriba indicada, tenemos el site 1 con ip 10.2.4.0/24, y el site 2 con ip 192.168.20.0/24
Para el tunel, seleccioné el rango 10.8.200.40/28, aunque a los efectos del ejemplo puede ser /24. Luego como cada site no tiene IP públicas fijas, vamos a usar los nombres de dns dinámicos site1.dyndns.org y site2.dyndns.org
Con la estructura general planteada, vamos por pasos...

Pasos

Clave

Lo primero que debemos hacer es crear una secret key, que no es más que un archivo que se utilizará en ambos lados de la VPN a los efectos de establecer el enlace y encriptar la información transmitida

Para ello ejecutamos el siguiente comando en cualquiera de los 2 linux

openvpn --genkey --secret /etc/home/miclave.key

Una vez creado el archivo miclave.key debemos copiarlo al site opuesto de su creación, para que ambos sites dispongan del mismo archivo al momento de la conexión

Para configurar el site crearemos un archivo conf para openvpn denominado connect_to_site2.conf en /etc/openvpn con el siguiente contenido

dev tun
port 1195
ifconfig 10.8.200.40 10.8.200.41
route 192.168.20.0 255.255.255.0
keepalive 10 60
persist-key
persist-tun
user nobody
group nobody
secret /home/miclave.key
cipher AES-256-CBC
remote site2.dyndns.org

Detalles:El primer renglón, indica el tipo de dispositvo que vamos a generar, o sea un tunel. Luego indicamos el port por defecto de openvpn (y si... pueden usar otro puerto si quieren...), a continuación, le indicamos los extremos local y remoto en IPs del tunel (tengan presente el tema de la ip dinámica... ya vamos a volver sobre eso..)
A continuación, indicamos el mantenimiento del tunel, la clave, que es un tunel site to site (persist-tun), usuario y grupo de ejecución, luego el archivo que generamos antes.. (pueden copiarlo a etc/openvpn para no tener que referenciar la ruta), y el nivel de crifrado...
El último renglón (por ahora..) del archivo de configuración es sumamente importante, pues es quien le dice donde está el extremo del tunel a nivel internet... normalmente usaríamos una IP pero como no la tenemos, usamos una URL que apunta a una ip dinámica

Para configurar el site 2 crearemos otro archivo conf para openvpn denominado connect_to_site1.conf en /etc/openvpn del equipo en site2 con el siguiente contenido

dev tun
port 1195
ifconfig 10.8.200.41 10.8.200.40
route 10.2.4.0 255.255.255.0
keepalive 10 60
persist-key
persist-tun
user nobody
group nobody
secret /home/miclave.key
cipher AES-256-CBC
remote site1.dyndns.org

Arranque y parada de la VPN

Obviamente como es una VPN site to site, queremos que inicie y se mantenga arriba constantmente, para lo que debemos crear un "servicio" que haga esto por nosotros...

En mi caso, como la distribución es CentOS, utilizamos el comando systemctl para habilitar la conexión como servicio, para ello usamos openvpn@ y el nombre del archivo que generamos inicialmente con la salvedad de cambiar .conf por .service

systemctl enable openvpn@connect_to_site2.service

Una vez creado...iniciamos la vpn con..

systemctl restart openvpn@connect_to_site2.service

... y ahi estmos.. la vpn debería enlazar y conectar ...

Monitoreo y Reinicio

Obviamente, como tenemos ips dinámicas, la VPN se va a caer de tanto en tanto.. no es ideal.. pero para los que vivimos en Argentina, sabemos que lo ideal siempre está lejos.. asi que podemos armarnos de un script para que monitoree la VPN y provoque un reinicio si ve que la misma se cae.

En el script que copio a continuación, se usa como parámetro la IP del tunel del site remoto, con lo cual, si dicha IP responde al PING implica que la VPN esta up and running

Si el script detecta el enlace caído, fuerza un reincio de la VPN, obviamente la linea systemctl restart openvpn@connect_to_site1.service que es la que reinicia la VPN debe invocar al archivo creado en cada site, por lo tanto si los archivos son de diferente nombre como en nuestro ejemplo, se deberá crear un script para cada site.

Ahhh... si.. me olvidé... el script también registra via logger los eventos de verificación ok y de reinicio, de forma que podamos saber que tan estable es la VPN.

Sencillo no?.. debería...

El comportamiento de esta puerta de enlace, es simple, si el paquete que se recibe es para la red cuya ruta está indicada en el tunel, entonces se tira el otro extremo... sino.. se tira al DG (Default Gateway)... con eso se evita que el tráfico a internet pase por la VPN

Pero que ocurre si en un extremo tenemos más de 1 red???? como lo indicamos...

Si, digamos, en el extremo del site 1 tenemos adicionalmente las redes 10.2.5.0/24 y 10.2.6.0/24, entonces... en el archivo del site 2 debemos agregar esas rutas... con lo que el archivo quedaría como..

dev tun
port 1195
ifconfig 10.8.200.41 10.8.200.40
route 10.2.4.0 255.255.255.0
route 10.2.5.0 255.255.255.0
route 10.2.6.0 255.255.255.0
keepalive 10 60
persist-key
persist-tun
user nobody
group nobody
secret /home/miclave.key
cipher AES-256-CBC
remote site1.dyndns.org

Ahhh.. pero la resolución de nombres???

Ahhh... ok.. las querés todas... bueno.. la resolución de nombres, con el tunnel up, es dependiente del sistema de resolución de nombres que se tenga implementado...
si en ambos lados hay servidores DNS que se puedan utilizar, bastará con configurar "conditional forwardings" para la resolución de los dominios cruzados de cada site, site1 contra site2 y viceversa... pero supongamos que site2, es un site chico y no tiene servers.. salvo el linux que acabamos de instalar en reemplazo del router... como solucionamos este tema... tenemos que decirle al linux que cuando se intente resolver nombres le consulte a un determinado DNS.. pero solo para algunos nombres.. entonces como deberíamos configurar...???
Los equpos en site2 deberían consultar al LInux por la resolución de nombres (normalmente en sites chicos los equipos se configuran con DNSs externos para resolución de nombres y esto no ayuda en este caso), luego configurar linux con un dnscache o como hicimos en este caso con el demoni dns masquerade

dnsmasq.d permite escuchar los requerimientos de resoluciön de nombres y enviarlos a los servidores configurados en el equipo como resolvers para la resoluciön de nombres, siendo su archivo de configuración (/etc/dnsmasq.conf) más o menos como el sigueinte...

bogus-priv
cache-size=5000
conf-dir=/etc/dnsmasq.d
dhcp-authoritative
dhcp-lease-max=1000
domain-needed
domain=site2.local
expand-hosts
no-negcache
port=53
resolv-file=/etc/resolv-peerdns.conf
strict-order
user=nobody
read-ethers

De este archivo se deduce que, el dominio local es site2.local y que se utilizan los servers indicados en /etc/resolv-peerdns.conf para la resolución de nombres, pero como dichos servers son normalmente externos, no tendrán idea del dominio en site1 ni de como resolver sus nombres, para lo cual agregaremos la siguiente linea

server=/site1.local/10.2.4.200

Asumiento que la ip 10.2.4.200

corresponde al DNS que es capaz de resolver los nombres de dominio site2.local

Conclusiones

Nuevamente, dista mucho de lo ideal enlazar una VPN entre sites que no tienen IP fija, y también es arriesgado, pero sin ninguna duda es económico.

OpenVPN es bastante seguro, sin embargo, como administradors debemos estar atento a las vulnerabilidades que pudieran surgir, y mejorar los enlaces en cada ocación posible

Lo mismo vale para las boxes linux que usemos en cada extremo...

 

 

Volver a lista de Notas